home *** CD-ROM | disk | FTP | other *** search
- /*
- ••••••••••••••••••••
- BitmapImageAccess.c
- David Surovell
-
- this file contains a routine that computes a histogram for
- any indexed (1-8 bits per pixel) gxBitmap shape
- ••••••••••••••••••••
- */
-
- #include <Types.h>
- #include <Memory.h>
-
- #include "graphics types.h"
- #include "graphics errors.h"
- #include "graphics routines.h"
-
-
- unsigned long *BitmapShape_GetIndexedCounts(
- gxShape sourceBits );
-
-
-
- unsigned long *BitmapShape_GetIndexedCounts(
- gxShape sourceBits )
- {
- gxBitmap sourceInfo, *sourceInfoRef;
- gxShapeAttribute curAttributes;
- OSErr errStat;
- unsigned char *sourcePtr, *rowPtr, curPixValue;
- unsigned long *curHistoData;
- long histoDataSize, sourceRowSize, structLen, i, j;
- Boolean isQDGXImage;
-
- /* make sure that this is a bitmap shape */
- if (sourceBits == nil)
- return nil;
- if (GXGetShapeType( sourceBits ) != gxBitmapType)
- return nil;
-
- /* make sure that this is an indexed bitmap shape */
- GXGetBitmap( sourceBits, &sourceInfo, nil );
- if ((sourceInfo.pixelSize < 1) || (sourceInfo.pixelSize > 8))
- return nil;
-
- /* if the image data was allocated by QDGX */
- isQDGXImage = ((sourceInfo.image == nil) || (sourceInfo.rowBytes <= 0));
- if (isQDGXImage)
- {
- /* load and lock image data */
- curAttributes = GXGetShapeAttributes( sourceBits );
- if (!(curAttributes & gxDirectShape))
- GXSetShapeAttributes( sourceBits, curAttributes | gxDirectShape );
- GXLockShape( sourceBits );
-
- /* get a reference to image data */
- sourceInfoRef = (gxBitmap*)GXGetShapeStructure( sourceBits, &structLen );
- if ((sourceInfoRef == nil) || (structLen < sizeof(gxBitmap)))
- return nil;
-
- sourceInfo = *sourceInfoRef;
- }
-
- /* allocate a buffer big enough to hold index counts */
- histoDataSize = (1L << sourceInfo.pixelSize) * sizeof(long);
- curHistoData = (unsigned long*)NewPtrClear( histoDataSize );
- errStat = MemError();
- if ((curHistoData == nil) || (errStat != noErr))
- return nil;
-
- /* count index values, one row at a time */
- sourcePtr = (unsigned char*)(sourceInfo.image);
- for (i=sourceInfo.height; i>0; i--)
- {
- rowPtr = sourcePtr;
- sourceRowSize = sourceInfo.width;
- while (sourceRowSize-- > 0)
- {
- curPixValue = *rowPtr;
- switch (sourceInfo.pixelSize)
- {
- case 8:
- curHistoData[curPixValue]++;
- break;
-
- case 4:
- for (j=2; j>0; j--)
- if (sourceRowSize > 0)
- {
- curHistoData[curPixValue & 0x0F]++;
- curPixValue >>= 4;
- sourceRowSize--;
- }
- break;
-
- case 2:
- for (j=4; j>0; j--)
- if (sourceRowSize > 0)
- {
- curHistoData[curPixValue & 0x03]++;
- curPixValue >>= 2;
- sourceRowSize--;
- }
- break;
-
- case 1:
- for (j=8; j>0; j--)
- if (sourceRowSize > 0)
- {
- curHistoData[curPixValue & 0x01]++;
- curPixValue >>= 1;
- sourceRowSize--;
- }
- break;
- }
-
- rowPtr++;
- }
-
- /* skip to the next row */
- sourcePtr = (unsigned char*)sourcePtr + sourceInfo.rowBytes;
- }
-
- /* if the image data was allocated by QDGX */
- if (isQDGXImage)
- {
- /* release the shape */
- GXUnlockShape( sourceBits );
- if (!(curAttributes & gxDirectShape))
- GXSetShapeAttributes( sourceBits, curAttributes );
- }
-
- return curHistoData;
- }
-
-
-